package cn.com.cetccst.basiccollection.basicinfo;

import android.Manifest;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityNr;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoNr;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;

//基础设备信息工具类
//这里基本列举实现了功能清单中基础属性里面能够通过AOSP获取的内容
//具体后期协议确定后再优化实现。
public class BasicInfoUtil {

    private static final String TAG = "BasicInfoUtil";

    private static DecimalFormat fileIntegerFormat = new DecimalFormat("#0");
    private static DecimalFormat fileDecimalFormat = new DecimalFormat("#0.#");

    public static String getScreenPixels(Context context) {
        DisplayMetrics outMetrics = context.getResources().getDisplayMetrics();
        return outMetrics.widthPixels + "*" + outMetrics.heightPixels;
    }

    /**
     * 单位换算
     *
     * @param size      unit in byte
     * @param isInteger whether returns sharp size
     * @return human readable string
     */
    public static String formatFileSize(long size, boolean isInteger) {
        DecimalFormat df = isInteger ? fileIntegerFormat : fileDecimalFormat;
        String fileSizeString = "0M";
        if (size < 1024 && size > 0) {
            fileSizeString = df.format((double) size) + "B";
        } else if (size < 1024 * 1024) {
            fileSizeString = df.format((double) size / 1024) + "K";
        } else if (size < 1024 * 1024 * 1024) {
            fileSizeString = df.format((double) size / (1024 * 1024)) + "M";
        } else {
            fileSizeString = df.format((double) size / (1024 * 1024 * 1024)) + "G";
        }
        return fileSizeString;
    }

    public static int getBattery(Context context) {
        BatteryManager bm = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
        int batLevel = 0;
        if (bm != null) {
            batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        }
        return batLevel;
    }

    /**
     * todo 删除这个，为了测试哪些静态数据可以获取到
     * Android 15 (API 35)
     * 安全补丁日期：2025-07-01
     * 硬件名称：mt6989
     * 构建版本号：PHZ110_15.0.0.840(CN01)
     * 厂商、型号：OPPO PHZ110 (PHZ110)
     * 内核名称：Linux
     * 内核版本：6.1.128-android14-11-o-g2f5c30d578c6
     * 基带版本：M_V3_P10,M_V3_P10
     */
    public static void printOSInfo(Context context) {
        Log.e(TAG, "Android " + Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ")");
        Log.e(TAG, Build.VERSION.SECURITY_PATCH);
        Log.e(TAG, Build.HARDWARE);
        Log.e(TAG, Build.DISPLAY);
        Log.e(TAG, Build.MANUFACTURER + " " + Build.MODEL + " (" + Build.PRODUCT + ")");
        Log.e(TAG, System.getProperty("os.name", "Unknown"));
        Log.e(TAG, System.getProperty("os.version", "Unknown"));
        Log.e(TAG, Build.getRadioVersion());

        Log.e(TAG, formatFileSize(getTotalMemory(), false));

        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        activityManager.getMemoryInfo(memoryInfo);
        long availableMem = memoryInfo.availMem;
        long totalMem = memoryInfo.totalMem;
        long advertisedMem = 0; //拓展后的内存
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            advertisedMem = memoryInfo.advertisedMem;
        }
        Log.e(TAG, formatFileSize(availableMem, false));
        Log.e(TAG, formatFileSize(totalMem, false));
        Log.e(TAG, formatFileSize(advertisedMem, false));
        Log.d(TAG, "Device IPv6 Address: " + getActiveNetworkIPv6Address(context));
        Log.d(TAG, "Device IPv6 Address: " + getLocalIpAddress());
        getPairedBTInfo();
    }

    public static String getActiveNetworkIPv6Address(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) {
            return null;
        }

        Network activeNetwork = cm.getActiveNetwork();
        if (activeNetwork == null) {
            return null;
        }

        LinkProperties linkProperties = cm.getLinkProperties(activeNetwork);
        if (linkProperties == null) {
            return null;
        }

        for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
            if (linkAddress.getAddress() instanceof Inet6Address) {
                Inet6Address v6Addr = (Inet6Address) linkAddress.getAddress();
                    String ip = v6Addr.getHostAddress();
                    int percentIndex = ip.indexOf('%');
                    if (percentIndex > 0) {
                        ip = ip.substring(0, percentIndex);
                    }
                    return ip; // 返回找到的第一个符合条件的全局 IPv6 地址
            }
        }
        return null;
    }

    public static long getTotalMemory() {
        String fileName = "/proc/meminfo"; // 系统内存信息文件:cite[3]:cite[8]
        String memTotalLine;
        long totalMemory = 0;
        try {
            FileReader fileReader = new FileReader(fileName);
            BufferedReader bufferedReader = new BufferedReader(fileReader, 8192);
            memTotalLine = bufferedReader.readLine(); // 读取第一行，通常为MemTotal:cite[3]:cite[8]
            String[] parts = memTotalLine.split("\\s+"); // 按空格分割:cite[3]:cite[8]
            if (parts.length > 1) {
                totalMemory = Long.parseLong(parts[1]); // 获取MemTotal的值，单位KB:cite[3]:cite[8]
            }
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return totalMemory * 1024; // 转换为字节，注意实际处理时需考虑异常和单位转换1111
    }

    public static String getNetworkTypeName(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        int type = telephonyManager.getNetworkType();

        switch (type) {
            case TelephonyManager.NETWORK_TYPE_GPRS:
            case TelephonyManager.NETWORK_TYPE_EDGE:
            case TelephonyManager.NETWORK_TYPE_CDMA:
            case TelephonyManager.NETWORK_TYPE_1xRTT:
            case TelephonyManager.NETWORK_TYPE_IDEN:
                return "2G";
            case TelephonyManager.NETWORK_TYPE_UMTS:
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
            case TelephonyManager.NETWORK_TYPE_EVDO_B:
            case TelephonyManager.NETWORK_TYPE_HSDPA:
            case TelephonyManager.NETWORK_TYPE_HSUPA:
            case TelephonyManager.NETWORK_TYPE_EHRPD:
            case TelephonyManager.NETWORK_TYPE_HSPAP:
            case TelephonyManager.NETWORK_TYPE_HSPA:
                return "3G";
            case TelephonyManager.NETWORK_TYPE_LTE:
            case 19:  //LTE_CA
                return "4G";
            case TelephonyManager.NETWORK_TYPE_NR:
                return "5G";
        }
        return "unknown";
    }

    public static long getCellInfo(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.e(TAG, "did not granted location permission");
            return 0;
        }

        List<CellInfo> cellInfos = telephonyManager.getAllCellInfo();
        for (CellInfo cellInfo : cellInfos) {
            if (cellInfo instanceof CellInfoGsm) {
                CellIdentityGsm gsm = ((CellInfoGsm) cellInfo).getCellIdentity();
                return gsm.getCid();
            }

            if (cellInfo instanceof CellInfoLte) {
                CellIdentityLte lte = ((CellInfoLte) cellInfo).getCellIdentity();
                return lte.getCi();
            }

            if (cellInfo instanceof CellInfoWcdma) {
                CellIdentityWcdma wcdma = ((CellInfoWcdma) cellInfo).getCellIdentity();
                return wcdma.getCid();
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                if (cellInfo instanceof CellInfoNr) {
                    CellIdentityNr nr = (CellIdentityNr) cellInfo.getCellIdentity();
                    return nr.getNci();
                }
            }
        }
        return 0;
    }

    public static void getPairedBTInfo() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Log.e(TAG, "device not support bluetooth,or bluetooth is closed");
            return;
        }

        Set<BluetoothDevice> pairedDevieces = bluetoothAdapter.getBondedDevices();
        for (BluetoothDevice device : pairedDevieces) {
            Log.e(TAG, "paired device : " + device.getName() + "-" + device.getAddress());
        }
        //todo json format
    }

    public static String getLocalIpAddress() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface networkInterface = interfaces.nextElement();
                // 跳过回环接口和未启用的接口
                if (networkInterface.isLoopback() || !networkInterface.isUp()) continue;

                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress address = addresses.nextElement();
                    // 只返回IPv4地址
                    if (!address.isLoopbackAddress() && address instanceof Inet4Address) {
                        return address.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static boolean isSystemPackage(Context context, String packageName) {
        try {
            int flags = context.getPackageManager().getPackageInfo(packageName, 0).applicationInfo.flags;
            return ((flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) || ((flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    public static int getInstallLocation(Context context, String packageName) {
        try {
            ApplicationInfo info = context.getPackageManager().getPackageInfo(packageName, 0).applicationInfo;
            return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ? 1 : 0; //0 :internal,1 : sd card
        } catch (Exception e) {
            return 0;
        }
    }
}
